.PHONY : all
# 声明all为伪目标（PHONY），避免与同名文件冲突。

DIR_BUILD := /home/wx/uuxiang/makefile/20_22/02/build
DIR_MODULE_INC := /home/wx/uuxiang/makefile/20_22/02/module/inc
DIR_COMMON_INC := /home/wx/uuxiang/makefile/20_22/02/common/inc
# 定义编译输出目录和公共头文件目录的路径。

DIR_SRC := src
DIR_INC := inc
# 定义源文件目录和头文件目录的路径。

TYPE_INC := .h
TYPE_SRC := .c
TYPE_OBJ := .o
TYPE_DEP := .dep
# 定义不同文件类型的扩展名，包括头文件（.h）、源文件（.c）、目标文件（.o）、依赖文件（.dep）。

AR := ar
ARFLAGS := crs
# 定义生成静态库的工具和其使用的参数。

CC := gcc
CFLAGS := -I$(DIR_INC) -I$(DIR_MODULE_INC) -I$(DIR_COMMON_INC)
# 定义编译器为gcc，CFLAGS包含了头文件搜索路径。

ifeq ($(DEBUG),true)
CFLAGS += -g
endif
# 如果变量DEBUG为true，则添加-g选项用于生成调试信息。

MODULE := $(realpath .)
MODULE := $(notdir $(MODULE))
DIR_OUTPUT := $(addprefix $(DIR_BUILD)/, $(MODULE))
# 获取当前目录的绝对路径，将模块名设置为当前目录的名称，并定义模块的输出目录。

OUTPUT := $(MODULE).a
OUTPUT := $(addprefix $(DIR_BUILD)/, $(OUTPUT))
# 定义最终生成的静态库文件名，并设置输出路径。

SRCS := $(wildcard $(DIR_SRC)/*$(TYPE_SRC))
OBJS := $(SRCS:$(TYPE_SRC)=$(TYPE_OBJ))
OBJS := $(patsubst $(DIR_SRC)/%, $(DIR_OUTPUT)/%, $(OBJS))
DEPS := $(SRCS:$(TYPE_SRC)=$(TYPE_DEP))
DEPS := $(patsubst $(DIR_SRC)/%, $(DIR_OUTPUT)/%, $(DEPS))
# 查找源文件，生成目标文件和依赖文件列表，并将它们从源目录映射到输出目录。

vpath %$(TYPE_INC) $(DIR_INC)
vpath %$(TYPE_INC) $(DIR_MODULE_INC)
vpath %$(TYPE_INC) $(DIR_COMMON_INC)
vpath %$(TYPE_SRC) $(DIR_SRC)
# 设置文件搜索路径，vpath用于在指定目录中查找特定类型的文件。

-include $(DEPS)
# 包含所有生成的依赖文件，如果依赖文件不存在则跳过（-表示忽略错误）。

all : $(OUTPUT)
	@echo "Success! Target ==> $(OUTPUT)"
# 定义默认目标all，生成最终的静态库，并打印成功信息。

$(OUTPUT) : $(OBJS)
	$(AR) $(ARFLAGS) $@ $^
# 规则：生成静态库，将目标文件归档为静态库。

$(DIR_OUTPUT)/%$(TYPE_OBJ) : %$(TYPE_SRC)
	$(CC) $(CFLAGS) -o $@ -c $(filter %$(TYPE_SRC), $^)
# 规则：编译源文件生成目标文件。

$(DIR_OUTPUT)/%$(TYPE_DEP) : %$(TYPE_SRC)
	@echo "Creating $@ ..."
	@set -e; \
	$(CC) $(CFLAGS) -MM -E $(filter %$(TYPE_SRC), $^) | sed 's,\(.*\)\.o[ :]*,$(DIR_OUTPUT)/\1$(TYPE_OBJ) $@ : ,g' > $@
# 规则：生成依赖文件。通过gcc的-MM选项生成依赖信息，并使用sed命令调整格式，将生成的依赖信息重定向到依赖文件中。
